package com.example.cinemasystemv2.repository;

import com.example.cinemasystemv2.entity.Screening;
import com.example.cinemasystemv2.entity.Movie;
import com.example.cinemasystemv2.entity.ScreeningRoom;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Repository
public interface ScreeningRepository extends JpaRepository<Screening, Long> {
    
    @Query("SELECT s FROM Screening s JOIN FETCH s.movie JOIN FETCH s.room LEFT JOIN FETCH s.orders WHERE s.movie = :movie")
    List<Screening> findByMovie(@Param("movie") Movie movie);
    
    @Query("SELECT s FROM Screening s JOIN FETCH s.movie WHERE s.room = :room")
    List<Screening> findByRoom(@Param("room") ScreeningRoom room);
    
    @Query("SELECT s FROM Screening s JOIN FETCH s.movie JOIN FETCH s.room WHERE s.id = :id")
    Optional<Screening> findByIdWithAssociations(@Param("id") Long id);
    
    @Query("SELECT s FROM Screening s JOIN FETCH s.movie JOIN FETCH s.room LEFT JOIN FETCH s.orders WHERE s.startTime >= :startTime AND s.startTime < :endTime")
    List<Screening> findByDateRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    @Query("SELECT s FROM Screening s WHERE s.movie = :movie AND s.startTime >= :startTime AND s.startTime < :endTime")
    List<Screening> findByMovieAndDateRange(@Param("movie") Movie movie, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    @Query("SELECT s FROM Screening s WHERE DATE(s.startTime) = DATE(:date)")
    List<Screening> findByDate(@Param("date") LocalDateTime date);
    
    @Query("SELECT s FROM Screening s JOIN FETCH s.movie JOIN FETCH s.room LEFT JOIN FETCH s.orders WHERE s.startTime >= :now ORDER BY s.startTime")
    List<Screening> findUpcomingScreenings(@Param("now") LocalDateTime now);
    
    @Query("SELECT s FROM Screening s WHERE s.room = :room AND (s.startTime < :endTime AND s.startTime >= :startTime)")
    List<Screening> findConflictingScreenings(@Param("room") ScreeningRoom room, 
                                            @Param("startTime") LocalDateTime startTime, 
                                            @Param("endTime") LocalDateTime endTime);
    
    @Query("SELECT s FROM Screening s WHERE s.movie.title LIKE %:keyword% OR s.room.name LIKE %:keyword%")
    List<Screening> searchScreenings(@Param("keyword") String keyword);
    
    @Query("SELECT s.id FROM Screening s ORDER BY s.id")
    List<Long> findAllIds();
}